﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	public class HYCableTray
	{
		public HYCableTray(CableTray cableTray)
		{
			this.cableTray = cableTray;
			this.isSeparate = false;
			this.InitCustomConnector(cableTray);
		}

		public HYCableTray(CableTray cableTray, XYZ globalPoint)
		{
			this.cableTray = cableTray;
			this.isSeparate = false;
			this.globalPoint = globalPoint;
			this.InitCustomConnector(cableTray);
		}

		private void InitCustomConnector(CableTray cableTray)
		{
			this.sideConnector = new List<Connector>();
			IList<HYConnector> list = new List<HYConnector>();
			ConnectorSetIterator connectorSetIterator = cableTray.ConnectorManager.Connectors.ForwardIterator();
			while (connectorSetIterator.MoveNext())
			{
				object obj = connectorSetIterator.Current;
				Connector connector = obj as Connector;
                if (1 == (int)connector.ConnectorType)
				{
					list.Add(new HYConnector(connector));
				}
                else if (2 == (int)connector.ConnectorType)
				{
					this.sideConnector.Add(connector);
				}
			}
			this.customConnectorStart = list.ElementAt(0);
			this.customConnectorEnd = list.ElementAt(1);
			this.startXYZ = this.customConnectorStart.XYZ;
			this.endXYZ = this.customConnectorEnd.XYZ;
		}

		public XYZ GetProject(XYZ point, bool unBound)
		{
			YJKLine hyline = new YJKLine(this.customConnectorStart.XYZ, this.customConnectorEnd.XYZ);
			hyline.MakeUnBound();
			return hyline.GetProject(point);
		}

		public XYZ GetLineProject(XYZ point)
		{
			YJKLine hyline = new YJKLine(this.customConnectorStart.XYZ, this.customConnectorEnd.XYZ);
			hyline.MakeUnBound();
			return hyline.GetProject(point);
		}

		public Connector GetAppropriateConnector(XYZ xyzIntersection)
		{
			Connector result = null;
			if (this.IsPointOnCableTrayCurveExtension(xyzIntersection))
			{
				result = ((xyzIntersection.DistanceTo(this.customConnectorStart.XYZ) < xyzIntersection.DistanceTo(this.customConnectorEnd.XYZ)) ? this.customConnectorStart.Connector : this.customConnectorEnd.Connector);
			}
			else if (this.IsPointOnCableTrayCurve(xyzIntersection))
			{
				if (this.globalPoint != null)
				{
					double num = Math.Abs(this.globalPoint.DistanceTo(xyzIntersection) + this.globalPoint.DistanceTo(this.customConnectorStart.XYZ) - xyzIntersection.DistanceTo(this.customConnectorStart.XYZ));
					double num2 = Math.Abs(this.globalPoint.DistanceTo(xyzIntersection) + this.globalPoint.DistanceTo(this.customConnectorEnd.XYZ) - xyzIntersection.DistanceTo(this.customConnectorEnd.XYZ));
					result = ((num > num2) ? this.customConnectorStart.Connector : this.customConnectorEnd.Connector);
				}
				else
				{
					result = ((xyzIntersection.DistanceTo(this.customConnectorStart.XYZ) < xyzIntersection.DistanceTo(this.customConnectorEnd.XYZ)) ? this.customConnectorStart.Connector : this.customConnectorEnd.Connector);
				}
			}
			return result;
		}

		public IList<Connector> GetAppropriateConnector(CableTray otherCableTray)
		{
			IList<Connector> list = new List<Connector>();
			HYCableTray hycableTray = new HYCableTray(otherCableTray);
			if (this.customConnectorStart.XYZ.DistanceTo(hycableTray.CustomConnectorStart.XYZ) < this.customConnectorStart.XYZ.DistanceTo(hycableTray.CustomConnectorEnd.XYZ))
			{
				if (this.customConnectorStart.XYZ.DistanceTo(hycableTray.CustomConnectorStart.XYZ) < this.customConnectorEnd.XYZ.DistanceTo(hycableTray.CustomConnectorStart.XYZ))
				{
					list.Add(this.customConnectorStart.Connector);
					list.Add(hycableTray.CustomConnectorStart.Connector);
				}
				else
				{
					list.Add(this.customConnectorEnd.Connector);
					list.Add(hycableTray.CustomConnectorStart.Connector);
				}
			}
			else if (this.customConnectorStart.XYZ.DistanceTo(hycableTray.CustomConnectorEnd.XYZ) < this.customConnectorEnd.XYZ.DistanceTo(hycableTray.CustomConnectorEnd.XYZ))
			{
				list.Add(this.customConnectorStart.Connector);
				list.Add(hycableTray.CustomConnectorEnd.Connector);
			}
			else
			{
				list.Add(this.customConnectorEnd.Connector);
				list.Add(hycableTray.CustomConnectorEnd.Connector);
			}
			return list;
		}

		public bool IsPointOnDuctCurve(XYZ xyz)
		{
			bool result = false;
			if (Math.Abs(xyz.DistanceTo(this.customConnectorStart.XYZ) + xyz.DistanceTo(this.customConnectorEnd.XYZ) - this.customConnectorStart.XYZ.DistanceTo(this.customConnectorEnd.XYZ)) < 0.0001)
			{
				result = true;
			}
			return result;
		}

		public bool IsCableTrayOnLine(CableTray otherCableTray)
		{
			bool result = false;
			HYCableTray hycableTray = new HYCableTray(otherCableTray);
			if (this.IsPointOnCableTrayLine(hycableTray.CustomConnectorStart.XYZ) && this.IsPointOnCableTrayLine(hycableTray.CustomConnectorEnd.XYZ))
			{
				result = true;
			}
			return result;
		}

		public bool IsPointOnCableTrayLine(XYZ xyz)
		{
			bool result = false;
			if (this.IsPointOnCableTrayCurve(xyz) || this.IsPointOnCableTrayCurveExtension(xyz))
			{
				result = true;
			}
			return result;
		}

		public bool IsPointOnCableTrayCurveExtension(XYZ xyz)
		{
			bool result = false;
			if (Math.Abs(Math.Abs(xyz.DistanceTo(this.customConnectorStart.XYZ) - xyz.DistanceTo(this.customConnectorEnd.XYZ)) - this.customConnectorStart.XYZ.DistanceTo(this.customConnectorEnd.XYZ)) < 0.0001)
			{
				result = true;
			}
			return result;
		}

		public bool IsPointOnCableTrayCurve(XYZ xyz)
		{
			bool result = false;
			if (Math.Abs(xyz.DistanceTo(this.customConnectorStart.XYZ) + xyz.DistanceTo(this.customConnectorEnd.XYZ) - this.customConnectorStart.XYZ.DistanceTo(this.customConnectorEnd.XYZ)) < 0.0001)
			{
				result = true;
			}
			return result;
		}

		public bool IsPointOnCableTrayCurve(XYZ xyz, double deviation)
		{
			bool result = false;
			if (Math.Abs(xyz.DistanceTo(this.customConnectorStart.XYZ) + xyz.DistanceTo(this.customConnectorEnd.XYZ) - this.customConnectorStart.XYZ.DistanceTo(this.customConnectorEnd.XYZ)) < 0.0001 && xyz.DistanceTo(this.customConnectorStart.XYZ) > deviation && xyz.DistanceTo(this.customConnectorEnd.XYZ) > deviation)
			{
				result = true;
			}
			return result;
		}

		public bool IsIntersection(CableTray cableTrayOther)
		{
			bool result = false;
			if (this.IntersectionPoint(cableTrayOther) != null)
			{
				result = true;
			}
			return result;
		}

		public XYZ IntersectionPoint(CableTray cableTrayOther)
		{
			XYZ result = null;
			LocationCurve locationCurve = this.cableTray.Location as LocationCurve;
			LocationCurve locationCurve2 = cableTrayOther.Location as LocationCurve;
			IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
			Line line = Line.CreateBound(locationCurve.Curve.GetEndPoint(0), locationCurve.Curve.GetEndPoint(1));
			Curve curve = Line.CreateBound(locationCurve2.Curve.GetEndPoint(0), locationCurve2.Curve.GetEndPoint(1));
			line.MakeUnbound();
			curve.MakeUnbound();
			SetComparisonResult setComparisonResult = line.Intersect(curve, out intersectionResultArray);
			if (4 != (int)setComparisonResult && intersectionResultArray != null && !intersectionResultArray.IsEmpty)
			{
				result = intersectionResultArray.get_Item(0).XYZPoint;
			}
			return result;
		}

		public XYZ GlobalPoint
		{
			get
			{
				return this.globalPoint;
			}
			set
			{
				this.globalPoint = value;
			}
		}

		public HYConnector CustomConnectorStart
		{
			get
			{
				return this.customConnectorStart;
			}
		}

		public HYConnector CustomConnectorEnd
		{
			get
			{
				return this.customConnectorEnd;
			}
		}

		public bool IsSeparate
		{
			get
			{
				return this.isSeparate;
			}
		}

		public XYZ StartXYZ
		{
			get
			{
				return this.startXYZ;
			}
			set
			{
				this.startXYZ = value;
			}
		}

		public XYZ EndXYZ
		{
			get
			{
				return this.endXYZ;
			}
			set
			{
				this.endXYZ = value;
			}
		}

		private void ChangeCableTray(CableTray newCableTray)
		{
			this.cableTray = newCableTray;
			this.InitCustomConnector(this.cableTray);
		}

		public IList<CableTray> Separate(XYZ xyz)
		{
			IList<CableTray> list = new List<CableTray>();
			if (!this.IsPointOnCableTrayCurve(xyz))
			{
				return null;
			}
			Document document = this.cableTray.Document;
			SubTransaction subTransaction = new SubTransaction(document);
			IList<CableTray> result;
			try
			{
				subTransaction.Start();
				ICollection<ElementId> collection = ElementTransformUtils.CopyElement(document, this.cableTray.Id, new XYZ(0.0, 0.0, 0.0));
				document.Regenerate();
				ICollection<ElementId> collection2 = ElementTransformUtils.CopyElement(document, this.cableTray.Id, new XYZ(0.0, 0.0, 0.0));
				document.Regenerate();
				CableTray cableTray = null;
				CableTray cableTray2 = null;
				foreach (ElementId elementId in collection)
				{
					cableTray = (document.GetElementById(elementId) as CableTray);
				}
				foreach (ElementId elementId2 in collection2)
				{
					cableTray2 = (document.GetElementById(elementId2) as CableTray);
				}
				Line curve = Line.CreateBound(this.customConnectorStart.XYZ, xyz);
				Line curve2 = Line.CreateBound(xyz, this.customConnectorEnd.XYZ);
				LocationCurve locationCurve = cableTray.Location as LocationCurve;
				LocationCurve locationCurve2 = cableTray2.Location as LocationCurve;
				locationCurve.Curve = curve;
				locationCurve2.Curve = curve2;
				this.ConnectorChange(cableTray);
				this.ConnectorChange(cableTray2);
				foreach (Connector connector in this.sideConnector)
				{
					document.Delete(this.GetConnectConnector(connector).Owner.Id);
				}
				CableTray cableTray3 = this.cableTray;
				this.ChangeCableTray(cableTray);
				document.Delete(cableTray3.Id);
				document.Regenerate();
				list.Add(cableTray);
				list.Add(cableTray2);
				subTransaction.Commit();
				result = list;
			}
			catch (Exception ex)
			{
				throw ex;
			}
			finally
			{
				if ((int)subTransaction.GetStatus() != 3)
				{
					subTransaction.RollBack();
				}
				else
				{
					this.isSeparate = true;
				}
			}
			return result;
		}

		private void ConnectorChange(CableTray newCableTray)
		{
			ConnectorSetIterator connectorSetIterator = newCableTray.ConnectorManager.Connectors.ForwardIterator();
			while (connectorSetIterator.MoveNext())
			{
				object obj = connectorSetIterator.Current;
				Connector connector = obj as Connector;
				if (connector != null)
				{
					if (connector.Origin.IsAlmostEqualTo(this.customConnectorStart.XYZ))
					{
						Connector connectConnector = this.GetConnectConnector(this.customConnectorStart.Connector);
						if (connectConnector != null)
						{
							this.customConnectorStart.Connector.DisconnectFrom(connectConnector);
							connector.ConnectTo(connectConnector);
							break;
						}
					}
					else if (connector.Origin.IsAlmostEqualTo(this.customConnectorEnd.XYZ))
					{
						Connector connectConnector = this.GetConnectConnector(this.customConnectorEnd.Connector);
						if (connectConnector != null)
						{
							this.customConnectorEnd.Connector.DisconnectFrom(connectConnector);
							connector.ConnectTo(connectConnector);
							break;
						}
					}
				}
			}
			this.SideConnectorChange(newCableTray);
		}

		private void SideConnectorChange(CableTray newCableTray)
		{
			Document document = newCableTray.Document;
			HYCableTray hycableTray = new HYCableTray(newCableTray);
			foreach (Connector connector in this.sideConnector)
			{
				if (hycableTray.IsPointOnCableTrayCurve(connector.Origin))
				{
					try
					{
						Connector sideConnectConnector = this.GetSideConnectConnector(connector);
						if (sideConnectConnector != null)
						{
							FamilyInstance familyInstance = document.Create.NewTakeoffFitting(sideConnectConnector, newCableTray);
							familyInstance.Symbol = (this.GetConnectConnector(connector).Owner as FamilyInstance).Symbol;
							this.FamilyInstanceParameterConvert(this.GetConnectConnector(connector).Owner as FamilyInstance, familyInstance, document);
						}
					}
					catch (Exception)
					{
					}
				}
			}
		}

		private Connector GetSideConnectConnector(Connector connector)
		{
			Connector result = null;
			Connector connectConnector = this.GetConnectConnector(connector);
			Element owner = connectConnector.Owner;
			if (owner is FamilyInstance)
			{
				ConnectorSetIterator connectorSetIterator = (owner as FamilyInstance).MEPModel.ConnectorManager.Connectors.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector connector2 = obj as Connector;
					if (connector2 != null && connector2.Owner.UniqueId == connectConnector.Owner.UniqueId && !connector2.Origin.IsAlmostEqualTo(connectConnector.Origin))
					{
						result = this.GetConnectConnector(connector2);
						break;
					}
				}
			}
			return result;
		}

		private Connector GetConnectConnector(Connector connector)
		{
			Connector result = null;
			if (connector.IsConnected)
			{
				ConnectorSetIterator connectorSetIterator = connector.AllRefs.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector connector2 = obj as Connector;
                    if (connector2 != null && connector2.Owner.UniqueId != connector.Owner.UniqueId && ((int)connector2.ConnectorType == 1 || (int)connector2.ConnectorType == 2 || (int)connector2.ConnectorType == 19))
					{
						result = connector2;
						break;
					}
				}
			}
			return result;
		}

		public void ParameterConvert(CableTray sourceCableTray, CableTray newCableTray, Document document)
		{
			SubTransaction subTransaction = new SubTransaction(document);
			subTransaction.Start();
			foreach (object obj in newCableTray.Parameters)
			{
				Parameter parameter = (Parameter)obj;
                switch ((int)parameter.StorageType)
				{
				case 1:
					if (!parameter.IsReadOnly)
					{
						parameter.Set(sourceCableTray.get_Parameter(parameter.Definition).AsInteger());
					}
					break;
				case 2:
					if (!parameter.IsReadOnly && !(parameter.Definition.Name == "偏移量") && !(parameter.Definition.Name == "OffSet"))
					{
						parameter.Set(sourceCableTray.get_Parameter(parameter.Definition).AsDouble());
					}
					break;
				case 3:
					if (!parameter.IsReadOnly && parameter.IsShared)
					{
						parameter.Set(sourceCableTray.get_Parameter(parameter.Definition).AsString());
					}
					break;
				case 4:
					if (!parameter.IsReadOnly)
					{
						parameter.Set(sourceCableTray.get_Parameter(parameter.Definition).AsElementId());
					}
					break;
				}
			}
			if (!new HYCableTray(newCableTray).IsZAxis())
			{
				Parameter parameter2 = newCableTray.get_Parameter(BuiltInParameter.RBS_OFFSET_PARAM);
				parameter2.Set(sourceCableTray.get_Parameter(parameter2.Definition).AsDouble());
			}
			if ((int)subTransaction.Commit() == 5)
			{
				subTransaction.RollBack();
			}
		}

		public void FamilyInstanceParameterConvert(FamilyInstance sourcefi, FamilyInstance newfi, Document document)
		{
			SubTransaction subTransaction = new SubTransaction(document);
			subTransaction.Start();
			foreach (object obj in newfi.Parameters)
			{
				Parameter parameter = (Parameter)obj;
                switch ((int)parameter.StorageType)
				{
				case 1:
					if (!parameter.IsReadOnly)
					{
						parameter.Set(sourcefi.get_Parameter(parameter.Definition).AsInteger());
					}
					break;
				case 2:
					if (!parameter.IsReadOnly)
					{
						parameter.Set(sourcefi.get_Parameter(parameter.Definition).AsDouble());
					}
					break;
				case 3:
					if (!parameter.IsReadOnly && parameter.IsShared)
					{
						parameter.Set(sourcefi.get_Parameter(parameter.Definition).AsString());
					}
					break;
				case 4:
					parameter.AsElementId();
					if (!parameter.IsReadOnly)
					{
						parameter.Set(sourcefi.get_Parameter(parameter.Definition).AsElementId());
					}
					break;
				}
			}
			Parameter parameter2 = newfi.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
			parameter2.Set(sourcefi.get_Parameter(parameter2.Definition).AsDouble());
			if ((int)subTransaction.Commit() == 5)
			{
				subTransaction.RollBack();
			}
		}

		public CableTray CableTray
		{
			get
			{
				return this.cableTray;
			}
		}

		public Curve GetLocationCurve()
		{
			return (this.cableTray.Location as LocationCurve).Curve;
		}

		public bool IsParallel(CableTray otherCableTray)
		{
			bool result = false;
			HYCableTray hycableTray = new HYCableTray(otherCableTray);
			XYZ xyz = this.customConnectorEnd.XYZ - this.customConnectorStart.XYZ;
			XYZ xyz2 = hycableTray.CustomConnectorEnd.XYZ - hycableTray.CustomConnectorStart.XYZ;
			double num = xyz.AngleTo(xyz2);
			if (Math.Abs(num - Math.PI) < 0.0001 || num < 0.0001)
			{
				result = true;
			}
			return result;
		}

		public bool IsXYParallel(CableTray otherCableTray)
		{
			bool result = false;
			HYCableTray hycableTray = new HYCableTray(otherCableTray);
			XYZ xyz = new XYZ(this.customConnectorEnd.XYZ.X, this.customConnectorEnd.XYZ.Y, 0.0) - new XYZ(this.customConnectorStart.XYZ.X, this.customConnectorStart.XYZ.Y, 0.0);
			XYZ xyz2 = new XYZ(hycableTray.CustomConnectorEnd.XYZ.X, hycableTray.CustomConnectorEnd.XYZ.Y, 0.0) - new XYZ(hycableTray.CustomConnectorStart.XYZ.X, hycableTray.CustomConnectorStart.XYZ.Y, 0.0);
			double num = xyz.AngleTo(xyz2);
			if (Math.Abs(num - Math.PI) < 0.0001 || num < 0.0001)
			{
				result = true;
			}
			return result;
		}

		public double GetDistance(CableTray otherCableTray)
		{
			double result = -1.0;
			if (this.IsParallel(otherCableTray))
			{
				HYCableTray hycableTray = new HYCableTray(otherCableTray);
				Line line = Line.CreateBound(hycableTray.CustomConnectorStart.XYZ, hycableTray.CustomConnectorEnd.XYZ);
				line.MakeUnbound();
				result = line.Distance(this.customConnectorStart.XYZ);
			}
			return result;
		}

		public Curve GetGlobalEdge()
		{
			Curve result = null;
			Options options = new Options();
			options.ComputeReferences = true;
			foreach (GeometryObject geometryObject in new YJKElement(this.cableTray).GetGeometry(options))
			{
				if (geometryObject is Solid)
				{
					foreach (object obj in (geometryObject as Solid).Edges)
					{
						Edge edge = (Edge)obj;
						if (edge.AsCurve().Distance(this.globalPoint) < 0.0001)
						{
							result = edge.AsCurve();
							break;
						}
					}
				}
			}
			return result;
		}

		public XYZ GetGlobalOnCenterLinePoint(XYZ gPoint)
		{
			XYZ result = null;
			if (gPoint != null)
			{
				Curve locationCurve = this.GetLocationCurve();
				new IntersectionResult();
				result = locationCurve.Project(gPoint).XYZPoint;
			}
			return result;
		}

		public void Rotate90()
		{
			Document document = this.cableTray.Document;
			Line line = Line.CreateBound(this.startXYZ, this.endXYZ);
			ElementTransformUtils.RotateElement(document, this.cableTray.Id, line, Math.PI*.5);
		}

		public Line GetCableTrayAxis()
		{
			return Line.CreateBound(this.customConnectorStart.XYZ, this.customConnectorEnd.XYZ);
		}

		public bool IsXAxis()
		{
			bool result = false;
			if ((this.customConnectorStart.XYZ - this.customConnectorEnd.XYZ).Normalize().IsAlmostEqualTo(new XYZ(1.0, 0.0, 0.0)) || (this.customConnectorStart.XYZ - this.customConnectorEnd.XYZ).Normalize().IsAlmostEqualTo(new XYZ(-1.0, 0.0, 0.0)))
			{
				result = true;
			}
			return result;
		}

		public bool IsYAxis()
		{
			bool result = false;
			if ((this.customConnectorStart.XYZ - this.customConnectorEnd.XYZ).Normalize().IsAlmostEqualTo(new XYZ(0.0, 1.0, 0.0)) || (this.customConnectorStart.XYZ - this.customConnectorEnd.XYZ).Normalize().IsAlmostEqualTo(new XYZ(0.0, -1.0, 0.0)))
			{
				result = true;
			}
			return result;
		}

		public bool IsZAxis()
		{
			bool result = false;
			if ((this.customConnectorStart.XYZ - this.customConnectorEnd.XYZ).Normalize().IsAlmostEqualTo(new XYZ(0.0, 0.0, 1.0)) || (this.customConnectorStart.XYZ - this.customConnectorEnd.XYZ).Normalize().IsAlmostEqualTo(new XYZ(0.0, 0.0, -1.0)))
			{
				result = true;
			}
			return result;
		}

		public ElementId GetSystemElementId()
		{
			return this.cableTray.get_Parameter(BuiltInParameter.RBS_DUCT_SYSTEM_TYPE_PARAM).AsElementId();
		}

		public bool IsSamePlan(CableTray otherCableTray)
		{
			bool result = false;
			Curve curve = (otherCableTray.Location as LocationCurve).Curve;
			if (Math.Abs(this.customConnectorStart.XYZ.Z - this.customConnectorEnd.XYZ.Z) < 0.0001 && Math.Abs(this.customConnectorStart.XYZ.Z - curve.GetEndPoint(0).Z) < 0.0001 && Math.Abs(curve.GetEndPoint(0).Z - curve.GetEndPoint(1).Z) < 0.0001)
			{
				result = true;
			}
			return result;
		}

		public bool Combine(CableTray otherCableTray)
		{
			SubTransaction subTransaction = null;
			bool result;
			try
			{
				Document document = this.cableTray.Document;
				IList<Connector> list = new List<Connector>();
				list = this.GetAppropriateConnector(otherCableTray);
				if (list.Count > 1 && (list[0].IsConnected || list[1].IsConnected))
				{
					throw new Exception("接头已经连接");
				}
				subTransaction = new SubTransaction(document);
				subTransaction.Start();
				bool flag = false;
				XYZ xyz = null;
				XYZ xyz2 = null;
				IList<Connector> distanceConnector = this.GetDistanceConnector(otherCableTray);
				IList<Connector> list2 = new List<Connector>();
				foreach (Connector connector in distanceConnector)
				{
					if (connector != null && connector.IsConnected)
					{
						Connector connectConnector = this.GetConnectConnector(connector);
						list2.Add(connectConnector);
						connector.DisconnectFrom(connectConnector);
					}
				}
				if (distanceConnector != null && distanceConnector.Count > 1)
				{
					xyz = distanceConnector[0].Origin;
					xyz2 = distanceConnector[1].Origin;
				}
				if (xyz != null && xyz2 != null)
				{
					Line curve = Line.CreateBound(xyz, xyz2);
					(this.cableTray.Location as LocationCurve).Curve = curve;
					document.Regenerate();
					this.ChangeCableTray(this.cableTray);
					foreach (Connector connector2 in list2)
					{
						if (connector2 != null)
						{
							if (connector2.Origin.IsAlmostEqualTo(this.customConnectorStart.XYZ))
							{
								this.customConnectorStart.Connector.ConnectTo(connector2);
							}
							else if (connector2.Origin.IsAlmostEqualTo(this.customConnectorEnd.XYZ))
							{
								this.customConnectorEnd.Connector.ConnectTo(connector2);
							}
						}
					}
					document.Delete(otherCableTray.Id);
					document.Regenerate();
				}
				subTransaction.Commit();
				result = flag;
			}
			catch (Exception ex)
			{
				throw ex;
			}
			finally
			{
				if (subTransaction != null && (int)subTransaction.GetStatus() != 3)
				{
					subTransaction.RollBack();
				}
			}
			return result;
		}

		public IList<Connector> GetDistanceConnector(CableTray otherCableTray)
		{
			HYCableTray hycableTray = new HYCableTray(otherCableTray);
			IList<Connector> list = new List<Connector>();
			Connector connector;
			Connector connector2;
			if (this.customConnectorStart.XYZ.DistanceTo(hycableTray.CustomConnectorStart.XYZ) > this.customConnectorStart.XYZ.DistanceTo(hycableTray.CustomConnectorEnd.XYZ))
			{
				if (this.customConnectorStart.XYZ.DistanceTo(hycableTray.CustomConnectorStart.XYZ) > this.customConnectorEnd.XYZ.DistanceTo(hycableTray.CustomConnectorStart.XYZ))
				{
					connector = this.customConnectorStart.Connector;
					connector2 = hycableTray.CustomConnectorStart.Connector;
				}
				else
				{
					connector = this.customConnectorEnd.Connector;
					connector2 = hycableTray.CustomConnectorStart.Connector;
				}
			}
			else if (this.customConnectorStart.XYZ.DistanceTo(hycableTray.CustomConnectorEnd.XYZ) > this.customConnectorEnd.XYZ.DistanceTo(hycableTray.CustomConnectorEnd.XYZ))
			{
				connector = this.customConnectorStart.Connector;
				connector2 = hycableTray.CustomConnectorEnd.Connector;
			}
			else
			{
				connector = this.customConnectorEnd.Connector;
				connector2 = hycableTray.CustomConnectorEnd.Connector;
			}
			if (connector != null && connector2 != null)
			{
				list.Add(connector);
				list.Add(connector2);
			}
			return list;
		}

		public bool CheckFirstElbow()
		{
			bool result = false;
			FamilySymbol transition = (this.cableTray.Document.GetElementById(this.cableTray.GetTypeId()) as CableTrayType).Transition;
			FamilySymbol elbow = (this.cableTray.Document.GetElementById(this.cableTray.GetTypeId()) as CableTrayType).Elbow;
			if (elbow != null && transition != null)
			{
				result = true;
			}
			return result;
		}

		public double GetXAxisAngle()
		{
			XYZ xyz;
			if (Math.Abs(this.customConnectorStart.XYZ.Y - this.customConnectorEnd.XYZ.Y) > 0.0001)
			{
				if (this.customConnectorStart.XYZ.Y > this.customConnectorEnd.XYZ.Y)
				{
					xyz = this.customConnectorEnd.XYZ - this.customConnectorStart.XYZ;
				}
				else
				{
					xyz = this.customConnectorStart.XYZ - this.customConnectorEnd.XYZ;
				}
			}
			else
			{
				xyz = new XYZ(1.0, 0.0, 0.0);
			}
			return xyz.AngleTo(new XYZ(1.0, 0.0, 0.0));
		}

		public void Rotate(double angle)
		{
			if (Math.Abs(this.customConnectorStart.XYZ.Z - this.customConnectorEnd.XYZ.Z) > 0.0001)
			{
				Document document = this.cableTray.Document;
				Line line;
				if (this.customConnectorStart.XYZ.Z < this.customConnectorEnd.XYZ.Z)
				{
					line = Line.CreateBound(this.customConnectorStart.XYZ, this.customConnectorEnd.XYZ);
				}
				else
				{
					line = Line.CreateBound(this.customConnectorEnd.XYZ, this.customConnectorStart.XYZ);
				}
				line.MakeUnbound();
				ElementTransformUtils.RotateElement(document, this.cableTray.Id, line, angle);
			}
		}

		private CableTray cableTray;

		private HYConnector customConnectorStart;

		private HYConnector customConnectorEnd;

		private bool isSeparate;

		private XYZ globalPoint;

		private IList<Connector> sideConnector;

		private XYZ startXYZ;

		private XYZ endXYZ;
	}
}
